package com.teamwings.ctrls.formCtrls.noField;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.teamwings.common.aspect.annotation.FormControl;
import com.teamwings.common.constant.FormConstant;
import com.teamwings.common.exception.ResultException;
import com.teamwings.common.jsqlparser.SelectParseHelper;
import com.teamwings.common.vo.Result;
import com.teamwings.ctrls.entity.DatabaseTableWithColumns;
import com.teamwings.modules.design.service.IDesignService;
import com.teamwings.modules.design.vo.FormTableVo;
import com.teamwings.modules.design.vo.FormVo;
import com.teamwings.modules.page.service.IPageService;
import com.teamwings.util.SpringContextUtil;
import lombok.Data;
import lombok.EqualsAndHashCode;
import net.sf.jsqlparser.JSQLParserException;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.common.util.SpringContextUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 让logicTable可以被系统扫描到
 * needField的作用
 *  1. 可以让该组件不被设置到FormTableCode的TABLE_FIELDS字段中
 *  2. 不用创建表字段
 *  3. 可以通过trigger调用该组件的方法
 */
@FormControl(type = "logic_table", needField = false, isLayout = true)
@EqualsAndHashCode(callSuper = true)
@Data
public class LogicTable extends com.teamwings.ctrls.formCtrls.layout.Table {

    public LogicTable() {
        super();
        this.type = "logic_table";
    }

    @Override
    public Result<?> trigger(
            FormConstant.TRIGGER_TYPE type,
            IPageService pageService,
            FormVo formDesignCode,
            Object paramsData
    ) {
        JSONObject jo = JSON.parseObject(paramsData + "");
        Integer listType = jo.getInteger("listType");

        // logicTable 相关方法
        // 1. 显示logicTable列表 （单表实现，sql显示）
        // 2. 根据sql语句，查询返回列字段
        if (type == FormConstant.TRIGGER_TYPE.CTRL_HANDLER) {
            if (listType.equals(0)) {
                String searchText = jo.getString("searchText");
                List<Map<String, String>> tableList = tableList(searchText);
                return Result.OK(tableList);
            } else if(listType.equals(1)) {
                // 根据sql语句，查询返回列字段
                String sql = jo.getString("sql");
//                List<String> columnList = this.getColumnBySql(pageService, sql);
                List<String> columnList = this.getColumnBySql(pageService, sql);
                return Result.OK(columnList);
            } else if(listType.equals(2)) {

            }
        }
        return Result.error("参数有误，查询失败。");
    }

    public List<String> getColumnBySql(IPageService pageService, String sql) {

        if (!sql.endsWith("limit 1") || !sql.endsWith("LIMIT 1")) {
            sql += " limit 1";
        }

        List<String> columnList = null;
        try {
            columnList = SelectParseHelper.getColumnBySql(pageService, sql);
        } catch (JSQLParserException e) {
            throw new ResultException("sql语句解析异常：" + e.getMessage());
        } catch (ResultException e) {
            throw new ResultException(e.getMessage());
        }

        return columnList;
    }

    // todo 此处可以使用缓存技术进行优化， 把tableList里表缓存起来
    public List<Map<String, String>> tableList(String searchText) {
        IDesignService designService = SpringContextUtil.getBean(IDesignService.class);
        // 表单设计相关的表
        List<FormTableVo> formTableList = designService.getLatestList();
        // 返回数据库中所有表 (里面包含表单设计相关的表)
        List<DatabaseTableWithColumns> allTableList = designService.allTableWithColumns();
        // 获取是表单数据库表名List
        List<String> isFormTableNameList = new ArrayList<>(formTableList.size());

        List<Map<String, String>> data = formTableList.stream().filter(entity -> {
            String tableCname = entity.getTableCname();
            return tableCname.contains(searchText);
        }).map(formTableVo -> {
            String tableName = formTableVo.getTableName();
            isFormTableNameList.add(tableName);
            Map<String, String> map = new HashMap<>();
            map.put("tableHeadId", formTableVo.getTableHeadId());
            map.put("formId", formTableVo.getTableHeadId());
            map.put("tableCname", formTableVo.getTableCname());
            map.put("fields", formTableVo.getTableFields());
            map.put("hasFormId", "true");
            return map;
        }).collect(Collectors.toList());

        // 如果包含中文，那么表示只搜索和表单设计相关的表。
        if (!CommonUtils.ifContainChinese(searchText)) {
            List<Map<String, String>> allList = allTableList.stream().filter(item -> {
                String tableName = item.getTableName();
                return tableName.contains(searchText) && !isFormTableNameList.contains(tableName);
            }).map(item -> {
                Map<String, String> map = new HashMap<>();
                map.put("tableHeadId", null);
                map.put("formId", null);
                map.put("tableCname", null);
                map.put("tableName", item.getTableName());
                map.put("fields", item.getColumns());
                map.put("hasFormId", "false");
                return map;
            }).collect(Collectors.toList());

            data.addAll(allList);
        }

        return data;
    }


}
